import numpy as np

def demonstrate_numpy_sorting_functions():
    """
    演示NumPy排序和条件筛选函数
    基于菜鸟教程的完整知识点实现
    """
    
    print("=" * 50)
    print("NumPy 排序和条件筛选函数演示")
    print("=" * 50)
    
    # 1. numpy.sort() 函数
    print("\n1. numpy.sort() 函数演示")
    print("-" * 30)
    
    # 基本排序
    a = np.array([[3, 7], [9, 1]])
    print("原始数组:")
    print(a)
    print("默认排序(按行):")
    print(np.sort(a))  # 默认按最后轴排序（行）
    print("按列排序:")
    print(np.sort(a, axis=0))  # axis=0 按列排序
    
    # 结构化数组排序
    dt = np.dtype([('name', 'S10'), ('age', int)])
    a_structured = np.array([("raju", 21), ("anil", 25), ("ravi", 17), ("amar", 27)], dtype=dt)
    print("结构化数组:")
    print(a_structured)
    print("按name字段排序:")
    print(np.sort(a_structured, order='name'))
    
    # 2. numpy.argsort() 函数
    print("\n2. numpy.argsort() 函数演示")
    print("-" * 30)
    
    x = np.array([3, 1, 2])
    print("原始数组:", x)
    indices = np.argsort(x)
    print("排序索引:", indices)
    print("通过索引重构排序数组:", x[indices])
    
    # 3. numpy.lexsort() 函数（多序列排序）
    print("\n3. numpy.lexsort() 函数演示")
    print("-" * 30)
    
    names = ('raju', 'anil', 'ravi', 'amar')
    divisions = ('f.y.', 's.y.', 's.y.', 'f.y.')
    # 注意：lexsort参数顺序与排序优先级相反（最后一个参数优先级最高）
    sorted_indices = np.lexsort((divisions, names))
    print("排序索引:", sorted_indices)
    print("排序结果:")
    for i in sorted_indices:
        print(f"{names[i]}, {divisions[i]}")
    
    # 4. numpy.msort() 函数
    print("\n4. numpy.msort() 函数演示")
    print("-" * 30)
    
    a = np.array([[3, 7], [9, 1]])
    print("msort排序(等价于sort(axis=0)):")
    print(np.msort(a))
    
    # 5. numpy.sort_complex() 函数
    print("\n5. numpy.sort_complex() 函数演示")
    print("-" * 30)
    
    # 实数排序
    real_nums = [5, 3, 6, 2, 1]
    print("实数排序:", np.sort_complex(real_nums))
    
    # 复数排序（先实部后虚部）
    complex_nums = [1+2j, 2-1j, 3-2j, 3-3j, 3+5j]
    print("复数排序:", np.sort_complex(complex_nums))
    
    # 6. partition() 和 argpartition() 函数
    print("\n6. partition() 和 argpartition() 函数演示")
    print("-" * 30)
    
    a = np.array([3, 4, 2, 1])
    print("原始数组:", a)
    print("分区排序(kth=3):", np.partition(a, 3))
    print("多分区排序(kth=[1,3]):", np.partition(a, (1, 3)))
    
    # 使用argpartition查找特定位置的元素
    arr = np.array([46, 57, 23, 39, 1, 10, 0, 120])
    print("查找第3小的值:", arr[np.argpartition(arr, 2)[2]])
    print("查找第2大的值:", arr[np.argpartition(arr, -2)[-2]])
    
    # 7. argmax() 和 argmin() 函数
    print("\n7. argmax() 和 argmin() 函数演示")
    print("-" * 30)
    
    a = np.array([[30, 40, 70], [80, 20, 10], [50, 90, 60]])
    print("多维数组:")
    print(a)
    print("全局最大值索引:", np.argmax(a))
    print("按轴0的最大值索引:", np.argmax(a, axis=0))
    print("按轴1的最大值索引:", np.argmax(a, axis=1))
    print("全局最小值索引:", np.argmin(a))
    print("按轴0的最小值索引:", np.argmin(a, axis=0))
    print("按轴1的最小值索引:", np.argmin(a, axis=1))
    
    # 8. nonzero() 函数
    print("\n8. nonzero() 函数演示")
    print("-" * 30)
    
    a = np.array([[30, 40, 0], [0, 20, 10], [50, 0, 60]])
    print("包含零的数组:")
    print(a)
    nonzero_indices = np.nonzero(a)
    print("非零元素索引:", nonzero_indices)
    print("非零元素值:", a[nonzero_indices])
    
    # 9. where() 函数
    print("\n9. where() 函数演示")
    print("-" * 30)
    
    x = np.arange(9.).reshape(3, 3)
    print("原始数组:")
    print(x)
    condition_indices = np.where(x > 3)
    print("大于3的元素索引:", condition_indices)
    print("满足条件的元素:", x[condition_indices])
    
    # 10. extract() 函数
    print("\n10. extract() 函数演示")
    print("-" * 30)
    
    x = np.arange(9.).reshape(3, 3)
    print("原始数组:")
    print(x)
    condition = np.mod(x, 2) == 0  # 偶数条件
    print("条件掩码(偶数):")
    print(condition)
    extracted = np.extract(condition, x)
    print("提取的偶数元素:", extracted)
    
    print("\n" + "=" * 50)
    print("所有函数演示完成！")
    print("=" * 50)

def additional_demonstrations():
    """
    额外的演示：排序算法比较和高级用法
    """
    print("\n" + "=" * 50)
    print("额外演示：排序算法和高级用法")
    print("=" * 50)
    
    # 不同排序算法比较
    large_array = np.random.randint(0, 1000, 1000)
    print("不同排序算法性能演示（1000个随机数）:")
    
    algorithms = ['quicksort', 'mergesort', 'heapsort']
    for algo in algorithms:
        sorted_arr = np.sort(large_array, kind=algo)
        print(f"{algo}: 前10个元素 {sorted_arr[:10]}...")
    
    # 条件筛选的高级用法
    print("\n条件筛选组合使用:")
    data = np.array([10, 25, 30, 45, 50, 65, 70, 85, 90, 95])
    
    # 多个条件组合
    condition1 = data > 30
    condition2 = data < 80
    combined_condition = condition1 & condition2
    
    print("原始数据:", data)
    print("30 < x < 80 的元素:", data[combined_condition])
    
    # 使用where进行条件替换
    replaced_data = np.where(data > 50, 100, data)  # 大于50的替换为100
    print("条件替换结果:", replaced_data)

if __name__ == "__main__":
    # 执行主要演示
    demonstrate_numpy_sorting_functions()
    
    # 执行额外演示
    additional_demonstrations()
    
    # 总结说明
    print("\n" + "=" * 70)
    print("知识点总结:")
    print("=" * 70)
    print("""
1. numpy.sort() - 返回排序后的数组副本，支持多轴排序
2. numpy.argsort() - 返回排序索引，用于重构排序数组
3. numpy.lexsort() - 多序列排序，优先级从后往前
4. 排序算法比较：
   - quicksort: 快速但不稳定
   - mergesort: 稳定但需要额外空间
   - heapsort: 不需要额外空间但不稳定
5. partition系列 - 部分排序，用于快速查找第k小/大元素
6. argmax/argmin - 极值索引查找
7. 条件筛选函数：
   - nonzero(): 非零元素索引
   - where(): 条件索引查找和替换
   - extract(): 条件元素提取
    """)